package com.bst.bsj.weixin;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.homewaimai.common.lang.SHAUtil;

/**
 * 基础支持 API
 * 
 * @author hansen 2014-1-12 上午03:44:04
 */
public abstract class APIBaseSupport {

    private static final Log logger = LogFactory.getLog(APIBaseSupport.class);

    // 过期时间
    public static final long expire = 7190 * 1000l;

    /**
     * 验证消息真实性
     * 
     * @param token 公众号自定义字符串
     * @param signature 微信签名
     * @param timestamp 时间戳
     * @param nonce 随机数
     * @return
     */
    public static boolean checkSignature(String token, String signature, String timestamp, String nonce) {

        List<String> list = new ArrayList<String>();
        list.add(token);
        list.add(timestamp);
        list.add(nonce);
        Collections.sort(list);

        StringBuffer buff = new StringBuffer();
        for (String str : list) {
            buff.append(str);
        }
        if (signature.equals(SHAUtil.hex_sha1(buff.toString()))) {
            return true;
        }
        return false;
    }

    /**
     * 获取媒体文件
     * 
     * @param access_token 访问token
     * @param media_id 媒体文件
     * @param path 临时存放媒体文件目录
     * @return
     */
    public static File getMedia(String access_token, String media_id, String path) {

        String f = System.getProperty("jsse.enableSNIExtension");
        if (!"false".equals(f)) {
            System.setProperty("jsse.enableSNIExtension", "false");
        }

        String targetURL = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=" + access_token
                           + "&media_id=" + media_id;
        GetMethod method = new GetMethod(targetURL);
        HttpClient client = new HttpClient();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);

        try {
            int status = client.executeMethod(method);

            if (status == HttpStatus.SC_OK) {
                Header header = method.getResponseHeader("Content-disposition");
                String vl = header.getValue();
                int index = vl.lastIndexOf(".");
                String postfix = ".jpg";

                // 获取媒体文件后缀
                if (index > 0) {
                    postfix = vl.substring(index, vl.length() - 1);
                }

                // 保存文件路径 /home/hansen/output/a.jpg
                String fileName = path + "/" + System.currentTimeMillis() + postfix;
                // 不能用getResponseBodyAsStream
                byte[] datas = method.getResponseBody();

                FileOutputStream fos = new FileOutputStream(fileName);
                fos.write(datas);
                fos.flush();
                fos.close();

                return new File(fileName);
            }

        } catch (Exception e) {

            logger.error("获取媒体文件出现异常", e);

        } finally {
            method.releaseConnection();
        }

        return null;
    }

    /**
     * 上传媒体 图片（image）: 128K，支持JPG格式 语音（voice）：256K，播放长度不超过60s，支持AMR\MP3格式 视频（video）：1MB，支持MP4格式 缩略图（thumb）：64KB，支持JPG格式
     * 
     * @return
     */
    public static String uploadMedia(String filePath, String access_token, String type) {

        String f = System.getProperty("jsse.enableSNIExtension");
        if (!"false".equals(f)) {
            System.setProperty("jsse.enableSNIExtension", "false");
        }

        File targetFile = new File(filePath);// TODO 指定上传文件
        String targetURL = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=" + access_token + "&type="
                           + type; // servleturl

        PostMethod filePost = new PostMethod(targetURL);

        try {
            // 通过以下方法可以模拟页面参数提交
            Part[] parts = { new FilePart(targetFile.getName(), targetFile) };
            filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
            HttpClient client = new HttpClient();
            client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
            int status = client.executeMethod(filePost);

            if (status == HttpStatus.SC_OK) {
                String responseContent = HttpClientUtil.getResponseBody(
                                                                        filePost.getResponseBodyAsStream(),
                                                                        HttpClientUtil.getResponseHeaderCharset(filePost));
                JSONObject ja = (JSONObject) JSON.parse(responseContent);
                String mid = (String) ja.get("media_id");

                // 错误消息
                if (mid == null) {
                    logger.error(ja.toJSONString());
                }

                return mid;

            }

        } catch (Exception ex) {

            logger.error("上传媒体出现异常", ex);

        } finally {
            filePost.releaseConnection();
        }

        return null;
    }

    /**
     * 获取 access_token（7200秒内有效），每次获取accesstoken会将前一个覆盖（失效）
     * 
     * @param appid
     * @param appsecret
     * @return
     */
    public static String getAccessToken(String appid, String appsecret) {

        String f = System.getProperty("jsse.enableSNIExtension");
        if (!"false".equals(f)) {
            System.setProperty("jsse.enableSNIExtension", "false");
        }

        // TODO Auto-generated method stub
        String targetURL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid
                           + "&secret=" + appsecret;
        GetMethod method = new GetMethod(targetURL);
        HttpClient client = new HttpClient();
        client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);

        try {
            int status = client.executeMethod(method);

            if (status == HttpStatus.SC_OK) {
                String responseContent = HttpClientUtil.getResponseBody(method.getResponseBodyAsStream(),
                                                                        HttpClientUtil.getResponseHeaderCharset(method));
                JSONObject ja = (JSONObject) JSON.parse(responseContent);

                // 获取 access_token
                String access_token = ja.getString("access_token");
                if (access_token == null) {
                    throw new Exception(responseContent);
                }

                return access_token;
            }

        } catch (Exception e) {

            logger.error("获取access_token异常", e);

        } finally {
            method.releaseConnection();
        }

        return null;
    }

    public static void main(String[] args) {

        // String mid = uploadMedia(
        // "/home/hansen/图片/cv-submit-tip.jpg",
        // "yZGkn8XdJZ8PoPnRkzar70YvruL0Y7KDrJ6gYT3Hpc5YNm0GIk97QnYkGwVe8ZxngdITxyvfmEScP2z_yDtSUM4NEnVyT7qGHQfzx7iSEZF17Fd1spTLC2pGd3PjgiWwfirr91MtD93RE-s6Ftb_yg",
        // "image");
        //
        // File f = getMedia(
        // "yZGkn8XdJZ8PoPnRkzar70YvruL0Y7KDrJ6gYT3Hpc5YNm0GIk97QnYkGwVe8ZxngdITxyvfmEScP2z_yDtSUM4NEnVyT7qGHQfzx7iSEZF17Fd1spTLC2pGd3PjgiWwfirr91MtD93RE-s6Ftb_yg",
        // mid, "/home/hansen/output");
        //
        // System.out.println(f.getAbsolutePath());

        System.out.println(getAccessToken("wxef0a31e6474cb4c7", "e8bb7fc6fe0f6294817c22860348a7d8"));

    }
}
